package rn;

import entidades.Processo;
import entidades.UnidadeMilitar;
import entidades.Usuario;
import excessoes.DAOException;
import excessoes.FabricaDAOException;
import excessoes.RNException;
import fabricas.DAOFabrica;
import interfaces.InterfaceProcessoDAO;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.faces.application.FacesMessage;
import util.FacesUtil;
import entidades.LogEventos;
import entidades.Setor;
import entidades.TramitacaoVolume;
import entidades.VolumeProcesso;

/**
 *
 * @author Marcelo Gomes Neto
 */
// Classe de Regras de Negócio
public class ProcessoRN 
{
    private InterfaceProcessoDAO interfaceProcessoDAO;

    public ProcessoRN() {
        this.interfaceProcessoDAO = DAOFabrica.criarProcessoDAO();
    }
    
    public Processo carregarProcesso(Integer id) throws Exception {
        return this.interfaceProcessoDAO.carregarProcesso(id);
    }
    public String salvarProcesso(Processo processo, Usuario usuario) 
    {
        try
        {
            Date dataAtual = new Date(System.currentTimeMillis());
            Integer idprocesso = processo.getIdprocesso();
            Integer idusu = usuario.getIdusuario();
            Integer idUnidadeUsu = usuario.getPessoa().getUnidade();
            Integer idSetorUsu = usuario.getPessoa().getSetor();
            String postoNome = usuario.getPessoa().getPostoGraduacao()+" "+usuario.getPessoa().getNomeGuerra();
            String pag = processo.getPag().toUpperCase().trim();
            String pam = processo.getPam().toUpperCase().trim();
            
            //Obtem a sigla da OM
            // Converte int para string a unidade e setor
            UnidadeMilitarRN umRN = new UnidadeMilitarRN();
            UnidadeMilitar um = umRN.carregarUnidadeMilitar(idUnidadeUsu);
            String omSigla = um.getSiglaOM();
                
            SetorRN stRN = new SetorRN();
            Setor st = stRN.carregarSetor(idSetorUsu);
            String stSigla = st.getSiglaSetor();
        
            //Verifica se o PAG já existe
            Processo contemPag = this.carregarProcessoPorPag(pag);
        
            //Verifica se o PA, já existe
            Processo contemPam = this.carregarProcessoPorPam(pam);
            
            //Instância o registro na tabela LOG_EVENTOS
            LogEventos logEventos = new LogEventos();
            LogEventosRN logEventosRN = new LogEventosRN();
            logEventos.setIdusuario(idusu);
            logEventos.setDataEvento(dataAtual);
        
            if (idprocesso == null || idprocesso == 0)
            {
                if (contemPag != null) {
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Pag já existe! Operação não realizada.", ""));
                    return null;
                }
                if (contemPam != null) {
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Pam já existe! Operação não realizada.", ""));
                    return null;
                }
                if (processo.getUnidadeSolicitante() == null || processo.getUnidadeSolicitante() == -1)
                {
                    String msg = "É necessário selecionar uma Unidade! Operação não realizada.";
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, ""));
                    return null;
                }
                if (processo.getSetorSolicitante() == null || processo.getSetorSolicitante() == -1)
                {
                    String msg = "É necessário selecionar um Setor! Operação não realizada.";
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, ""));
                    return null;
                }
                if (processo.getDataProcesso() == null)
                {
                    String msg = "É necessário informar a data do processo! Operação não realizada.";
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, ""));
                    return null;
                }
                if (processo.getObjeto() == null || processo.getObjeto().equals(""))
                {
                    String msg = "É necessário preencher o campo despacho! Operação não realizada.";
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, ""));
                    return null;
                }

                if (contemPag == null || contemPam == null) 
                {
                    VolumeProcesso volumeProcesso = new VolumeProcesso();
                    //Seta os registros da tabela TRAMITACAO
                    TramitacaoVolume tramitacaoVolume = new TramitacaoVolume();  
                    Set<TramitacaoVolume> tramita = new HashSet<>();
                    tramitacaoVolume.setDataTramitacao(dataAtual);
                    tramitacaoVolume.setRemetente(postoNome);
                    tramitacaoVolume.setUnidadeRemetente(omSigla);
                    tramitacaoVolume.setSetorRemetente(stSigla); //No cadastro do PAG, pega o setor de usuário que cadastrou o pag.
                    tramitacaoVolume.setUnidadeDestino(omSigla);
                    tramitacaoVolume.setSetorDestino(stSigla);
                    tramitacaoVolume.setDespacho("Abertura de processo (Vol. 1)");
                    tramita.add(tramitacaoVolume); 
                    tramitacaoVolume.setVolumeProcesso(volumeProcesso);
            
                    volumeProcesso.setTramitacaoVolume(tramita);
                    volumeProcesso.setUnidadeAtual(idUnidadeUsu);
                    volumeProcesso.setSetorAtual(idSetorUsu);
                    volumeProcesso.setCadastradoPor(postoNome);
                    volumeProcesso.setDataCadastramento(dataAtual);
                    volumeProcesso.setDataEntradaSetor(dataAtual);
                    volumeProcesso.setEncaminhadoPor(postoNome);
                    volumeProcesso.setVolume(1);
                    volumeProcesso.setProcesso(processo);
                    processo.getVolumeProcesso().add(volumeProcesso);
                    processo.setStatus(1);
                    processo.setCadastradoPor(postoNome);
                    processo.setDataCadastramento(dataAtual);
                    this.interfaceProcessoDAO.incluirProcesso(processo);
                
                    // Registra na tabela Log_Eventos
                    logEventos.setDescricao("o usuário "+postoNome+" ("+omSigla+") cadastrou o processo nº "+pag+".");
                    logEventosRN.salvarEvento(logEventos);
                    //Retorna ao usuário mensagem de confirmação
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Processo cadastrado com sucesso!", ""));
                }
            }
            else
            {
                if (processo.getUnidadeSolicitante() == null || processo.getUnidadeSolicitante() == -1)
                {
                    String msg = "É necessário selecionar uma Unidade! Operação não realizada.";
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, ""));
                    return null;
                }
                if (processo.getSetorSolicitante() == null || processo.getSetorSolicitante() == -1)
                {
                    String msg = "É necessário selecionar um Setor! Operação não realizada.";
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, ""));
                    return null;
                }
                if (processo.getDataProcesso() == null)
                {
                    String msg = "É necessário informar a data do processo! Operação não realizada.";
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, ""));
                    return null;
                }
                if (processo.getObjeto() == null || processo.getObjeto().equals(""))
                {
                    String msg = "É necessário preencher o campo despacho! Operação não realizada.";
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, ""));
                    return null;
                }
                else 
                {
                    processo.setPag(pag);
                    processo.setPam(pam);
                    this.interfaceProcessoDAO.atualizarProcesso(processo);

                    // Registra na tabela Log_Eventos
                    logEventos.setDescricao("o usuário "+postoNome+" ("+omSigla+") alterou o processo nº "+pag+".");
                    logEventosRN.salvarEvento(logEventos);
                    FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Processo alterado com sucesso!", ""));
                }
            }
        }
        catch (Exception e) {
        }
        return null;
    }
    
    public void atualizarProcesso(Processo processo) throws DAOException {
        this.interfaceProcessoDAO.atualizarProcesso(processo);
    }
    
    //Status 1 == ATIVO
    //Status 2 == ARQUIVADO
    public void manterProcesso(Processo processo, Usuario usuario) throws DAOException, FabricaDAOException, Exception
    {
        Date dataAtual = new Date(System.currentTimeMillis());
        int status = processo.getStatus();
        Integer idusu = usuario.getIdusuario();
        Integer idUnidade = usuario.getPessoa().getUnidade();
        //String postoNome = usuario.getPessoa().getNome();
        String nomeUsuario = usuario.getPessoa().getPostoGraduacao()+" "+usuario.getPessoa().getNomeGuerra();
        String pag = processo.getPag();
        String motivo = processo.getMotivoArquivamento();
        //String nomeUsuarioAdmin = solicitacao.getUsuario().getPessoa().getPostoGraduacao()+" "+solicitacao.getUsuario().getPessoa().getNomeGuerra();
        
        //Obtem a sigla da OM
        UnidadeMilitarRN unidadeMilitarRN = new UnidadeMilitarRN();
        UnidadeMilitar unidade = unidadeMilitarRN.carregarUnidadeMilitar(idUnidade);
        String siglaOM = unidade.getSiglaOM();
        
        // Seta os atributos para Log_Eventos
        LogEventos logEventos = new LogEventos();
        LogEventosRN logEventosRN = new LogEventosRN();
        logEventos.setIdusuario(idusu);
        logEventos.setDataEvento(dataAtual);
        
        //ARQUIVAR
        if (status == 1) {
            if (motivo == null || motivo.equals("")) {
                FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "É necessário informar o motivo! Operação não realizada.", ""));
            }
            else {
                processo.setStatus(2);
                this.interfaceProcessoDAO.manterProcesso(processo);
                logEventos.setDescricao("o usuário "+nomeUsuario+" ("+siglaOM+") arquivou o processo nº "+pag+".");
                logEventosRN.salvarEvento(logEventos);
                FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Processo arquivado com sucesso!", ""));
            }
        }
        
        //DESARQUIVAR
        if (status == 2) {
            processo.setStatus(1);
            processo.setMotivoArquivamento(null);
            this.interfaceProcessoDAO.manterProcesso(processo);
            logEventos.setDescricao("o usuário "+nomeUsuario+" ("+siglaOM+") desarquivou o processo nº "+pag+".");
            logEventosRN.salvarEvento(logEventos);
            FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Processo desarquivado com sucesso!", ""));
        }
    }
    
    public void excluirProcesso(Processo processo, Usuario usuario) throws RNException, DAOException, FabricaDAOException, Exception 
    {
        Date dataAtual = new Date(System.currentTimeMillis());
        Integer idusu = usuario.getIdusuario();
        Integer idUnidade = usuario.getPessoa().getUnidade();
        //String postoNome = usuario.getPessoa().getNome();
        String nomeUsuario = usuario.getPessoa().getPostoGraduacao()+" "+usuario.getPessoa().getNomeGuerra();
        String pag = processo.getPag();
        
        //Obtem a sigla da OM
        UnidadeMilitarRN unidadeMilitarRN = new UnidadeMilitarRN();
        UnidadeMilitar unidade = unidadeMilitarRN.carregarUnidadeMilitar(idUnidade);
        String siglaOM = unidade.getSiglaOM();
        
        LogEventos logEventos = new LogEventos();
        LogEventosRN logEventosRN = new LogEventosRN();
        logEventos.setIdusuario(idusu);
        logEventos.setDataEvento(dataAtual);

        Integer status = processo.getStatus();
        if (status == 1) {
            this.interfaceProcessoDAO.excluirProcesso(processo);
            logEventos.setDescricao("o usuário "+nomeUsuario+" ("+siglaOM+") excluiu o processo nº "+pag+".");
            logEventosRN.salvarEvento(logEventos);
            FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Processo excluído com sucesso!", ""));
        }
        else {
            FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "O processo nº "+pag+" não pode ser excluído! O processo está arquivado.", ""));
        }
    }

    public List<Processo> listar() {
        return this.interfaceProcessoDAO.listarProcesso();
    }
    
    public List<Processo> listarProcessoPorStatus(int status) 
    {
        List<Processo> lista;
        lista = this.interfaceProcessoDAO.listarProcessoPorStatus(status);
        if (lista.isEmpty() || lista == null) {
            FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Não há informações para os parâmetros informados!", ""));
            return null;
        }
        return lista;
    }
    
    public Object totalProcesso() {
        return this.interfaceProcessoDAO.totalProcesso();
    }
    
    public Object totalProcessoPorStatus(int status) {
        return this.interfaceProcessoDAO.totalProcessoPorStatus(status);
    }
    
    public List<Processo> listarProcessoPorPeriodo(Date dataIni, Date dataFim, int status) {
        return this.interfaceProcessoDAO.listarProcessoPorPeriodo(dataIni, dataFim, status);
    }
    
    public List<Processo> listarProcessoPorOM(Integer status, Integer unidade) {
        return this.interfaceProcessoDAO.listarProcessoPorOM(status, unidade);
    }
    
    public Processo buscarPorPag(String pag) {
        return this.interfaceProcessoDAO.buscarPorPag(pag);
    }
    
    public Processo buscarPorPam(String pam) {
        return this.interfaceProcessoDAO.buscarPorPam(pam);
    }
    
    public Integer retornaUltimoID() {
        return this.interfaceProcessoDAO.retornaUltimoID();
    }
    
    public Processo carregarProcessoPorPag(String pag) throws DAOException {
        return this.interfaceProcessoDAO.carregarProcessoPorPag(pag);
    }
    
    public Processo carregarProcessoPorPam(String pam) throws DAOException {
        return this.interfaceProcessoDAO.carregarProcessoPorPam(pam);
    }
}